import {isEmpty, real} from '@/utils/CommonUtils';
import {postAction} from '@/request/BaseRequest';

let Auth = {
  edit: 'edit',
  browse: 'browse',
  hide: 'hide',
};

let NotNull = {
  yes: "1",
  not: "0",
};

export default class {
  formDefinition;
  formData;
  viewAction;
  authData = {
    field_0001: {
      auth: Auth.edit,
      notNull: NotNull.yes
    },
    field_0002: {
      auth: Auth.edit,
      notNull: NotNull.yes
    },
    subAuthDatas: [
      {
        formId: 'asdf',
        authDatas: [
          {
            id: 'sadf',
            field_0001: {
              auth: Auth.edit,
              notNull: NotNull.yes
            },
            field_0002: {
              auth: Auth.edit,
              notNull: NotNull.yes
            }
          }
        ]
      }
    ]
  };

  constructor(formDefinition, formData, viewAction) {
    this.formDefinition = real(formDefinition);
    this.formData = real(formData);
    this.viewAction = real(viewAction);
    this.initAuthData();
  }

  initAuthData() {
    let res = {};
    this.initMainAuthData(res);
    this.initSubAuthData(res);
    this.authData = res;
  }

  initMainAuthData(res) {
    if (isEmpty(this.formDefinition)) return;
    let {formFields} = this.formDefinition;
    if (isEmpty(formFields)) formFields = [];
    formFields.forEach(field => {
      let {tableFieldName} = field;
      res[tableFieldName] = this.createEmptyAuth();
    });
  }

  initSubAuthData(res) {
    if (isEmpty(this.formData)) {
      res.subAuthDatas = [];
      return;
    }
    let subFormDatas = this.formData.subFormDatas;
    if (isEmpty(subFormDatas)) {
      res.subAuthDatas = [];
      return;
    }
    let subAuthDatas = [];

    subFormDatas.forEach(subFormData => {
      let {formId, formDatas} = subFormData;
      let fields = this.getSubFormFieldsById(formId);
      let authDatas = [];
      let subAuthData = {formId, authDatas};

      formDatas.forEach(rowData => {
        let authDataItem = {id: rowData.id};
        fields.forEach(field => {
          let {tableFieldName} = field;
          authDataItem[tableFieldName] = this.createEmptyAuth();
        });
        authDatas.push(authDataItem);
      });

      subAuthDatas.push(subAuthData);
    });

    res.subAuthDatas = subAuthDatas;
  }

  getSubFormById(id) {
    let {subForms} = this.formDefinition;
    let subForm = subForms.find(s => s.subForm.id === id);
    if (isEmpty(subForm)) {
      throw new Error('渲染子表报错: 根据子表id: ' + id + '没有找到子表');
    }

    return subForm.subForm;
  }

  getSubFormFieldsById(id) {
    let {subForms} = this.formDefinition;
    let subForm = subForms.find(s => s.subForm.id === id);
    if (isEmpty(subForm)) {
      throw new Error('渲染子表报错: 根据子表id: ' + id + '没有找到子表');
    }

    return subForm.fields;
  }

  getSubAuthDataByFormId(formId) {
    let {subAuthDatas} = this.authData;
    let res = subAuthDatas.find(s => s.formId === formId);
    if (isEmpty(res)) {
      subAuthDatas.push(res = {
        formId, authDatas: [],
      });
    }
    return res;
  }

  addSubTableRow(subForm, rowData) {
    let subAuthData = this.getSubAuthDataByFormId(subForm.id);
    let {authDatas} = subAuthData;
    let fields = this.getSubFormFieldsById(subForm.id);

    let newAuth = {};
    newAuth.id = rowData.id;
    fields.forEach(field => {
      newAuth[field.tableFieldName] = this.createEmptyAuth();
    });
    authDatas.push(newAuth);
  }

  getMainFieldAuth(field) {
    field = real(field);
    let {tableFieldName} = field;
    return this.authData[tableFieldName].auth;
  }

  getMainFieldNotNull(field) {
    let {tableFieldName} = field;
    return this.authData[tableFieldName].notNull;
  }

  mainFieldValueChange(fieldDefinition, formData) {
    let updateAction = this.createMainUpdateAction(fieldDefinition, formData);
    this.loading = true;
    postAction('/plat/updateAction', updateAction).then(data => {
      this.loading = false;
      if (data.success) {
        let result = data.result;
        this.setUpdateResultAuthData(result);
      }
    });
  }

  subFieldValueChange(fieldDefinition, formData, dataId) {
    let updateAction = this.createSubUpdateAction(fieldDefinition, formData, dataId);
    this.loading = true;
    postAction('/plat/updateAction', updateAction).then(data => {
      this.loading = false;
      if (data.success) {
        let result = data.result;
        this.setUpdateResultAuthData(result);
      }
    });
  }

  setUpdateResultAuthData(result) {
    if (isEmpty(result.setAuth)) return;
    result.setAuth.forEach(authSetter => {
      if (this.isAuthSetterMainForm(authSetter)) {

        if (isEmpty(this.authData[authSetter.fieldName])) {
          return//如果是不在表单字段定义里面的, 那就忽略, 例如create_time
        }
        this.authData[authSetter.fieldName].auth = authSetter.auth;
        this.authData[authSetter.fieldName].notNull = authSetter.notNull;
      } else {
        let subForm = this.getSubFormByFormName(authSetter.formName);
        let subAuthData = this.getSubAuthDataByFormId(subForm.id);
        let {authDatas} = subAuthData;
        let authData = authDatas.find(a => a.id === authSetter.dataId);
        if (isEmpty(authData[authSetter.fieldName])) {
          return//如果是不在表单字段定义里面的, 那就忽略, 例如create_time
        }
        authData[authSetter.fieldName].auth = authSetter.auth;
        authData[authSetter.fieldName].notNull = authSetter.notNull;
      }
    });
  }

  getSubFormByFormName(formName) {
    let subForm = this.formDefinition.subForms.find(s => s.subForm.formName === formName);
    if (isEmpty(subForm)) return null;
    return subForm.subForm;
  }

  isAuthSetterMainForm(authSetter) {
    if (authSetter.formName === this.formDefinition.form.formName) {
      return true;
    }
    return false;
  }

  createMainUpdateAction(fieldDefinition, formData) {
    return {
      mainFormId: this.formDefinition.form.id,
      formName: this.formDefinition.form.formName,
      fieldName: fieldDefinition.tableFieldName,
      main: true,
      formBean: formData,
      viewActionId: this.viewAction.id
    };
  }

  createSubUpdateAction(fieldDefinition, formData, dataId) {
    let subForm = this.getSubFormById(fieldDefinition.formId);
    return {
      mainFormId: this.formDefinition.form.id,
      formName: subForm.formName,
      fieldName: fieldDefinition.tableFieldName,
      main: false,
      formBean: formData,
      viewActionId: this.viewAction.id,
      dataId
    };
  }

  updatAllAuth(updatAllAuthContext) {
    return new Promise((success, err) => {
      postAction('/plat/updatAllAuth', updatAllAuthContext).then(data => {
        if (data.success) {
          let result = data.result;
          this.setUpdateResultAuthData(result);
          success();
        }
      });
    });
  }

  getSubFieldAuth(field, rowData) {
    let subForm = this.getSubFormById(field.formId);
    let subAuthData = this.getSubAuthDataByFormId(subForm.id);
    if (isEmpty(subAuthData)) return;
    let {authDatas} = subAuthData;

    if (isEmpty(authDatas)) return;
    let auth = authDatas.find(authData => authData.id === rowData.id);
    if (!isEmpty(auth)) {
      return auth[field.tableFieldName].auth;
    }
  }

  getSubFieldNotNull(field, rowData) {
    let subForm = this.getSubFormById(field.formId);
    let subAuthData = this.getSubAuthDataByFormId(subForm.id);
    if (isEmpty(subAuthData)) return;
    let {authDatas} = subAuthData;

    if (isEmpty(authDatas)) return;
    let auth = authDatas.find(authData => authData.id === rowData.id);
    if (!isEmpty(auth)) {
      return auth[field.tableFieldName].notNull;
    }
  }

  updateSubFormRowAuth(rowData, subForm, formData) {
    let updateSubFormRowAuthContext = {
      viewActionId: this.viewAction.id,
      formBean: formData,
      formsonBean: rowData
    };

    return new Promise((success, err) => {
      postAction("/plat/updatSubFormRowAuth", updateSubFormRowAuthContext).then(data => {
        if (data.success) {
          let result = data.result;
          this.setUpdateResultAuthData(result);
          success(result);
        }
      });
    });
  }

  createEmptyAuth() {
    return {
      auth: Auth.browse,
      notNull: NotNull.not
    };
  }
};

